package xyz.yuzegod.megawalls.util;

import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import net.citizensnpcs.api.CitizensAPI;
import net.minecraft.server.v1_8_R3.*;
import net.minecraft.server.v1_8_R3.PacketPlayInClientCommand.EnumClientCommand;
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
import net.skinsrestorer.api.PlayerWrapper;
import net.skinsrestorer.api.property.BukkitProperty;
import net.skinsrestorer.bukkit.SkinsRestorer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import xyz.yuzegod.megawalls.MegaWalls;
import xyz.yuzegod.megawalls.game.GamePlayer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class PlayerUtils {
    static SkinsRestorer skinsRestorer= (SkinsRestorer) Bukkit.getPluginManager().getPlugin("SkinsRestorer");
     public static void respawn(final Player player) {
          Bukkit.getScheduler().runTaskLater(MegaWalls.getInstance(), new Runnable() {
               public void run() {
                    PacketPlayInClientCommand packet = new PacketPlayInClientCommand(EnumClientCommand.PERFORM_RESPAWN);
                    ((CraftPlayer)player).getHandle().playerConnection.a(packet);
               }
          }, 1L);
     }

     public static void skinChangeNoKill(final CraftPlayer cp, final String value, final String signature) {
          GameProfile profile = cp.getProfile();
          profile.getProperties().put("textures", new Property("textures", value, signature));
          Collection<Property> prop = profile.getProperties().get("textures");
          cp.getProfile().getProperties().putAll("textures", prop);
          PacketPlayOutEntityDestroy pds = new PacketPlayOutEntityDestroy(new int[]{cp.getEntityId()});
          sendPacket(pds);
          PacketPlayOutPlayerInfo tab = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{cp.getHandle()});
          sendPacket(tab);
          (new BukkitRunnable() {
               public void run() {
                    PacketPlayOutPlayerInfo tabadd = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[]{cp.getHandle()});
                    PlayerUtils.sendPacket(tabadd);
                    PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(cp.getHandle());
                    Iterator var3 = Bukkit.getOnlinePlayers().iterator();

                    while(var3.hasNext()) {
                         Player pls = (Player)var3.next();
                         if (!pls.getName().equals(cp.getName())) {
                              ((CraftPlayer)pls).getHandle().playerConnection.sendPacket(spawn);
                         }
                    }

               }
          }).runTaskLater(MegaWalls.getInstance(), 5L);
          Bukkit.getScheduler().runTaskLater(MegaWalls.getInstance(), new Runnable() {
               public void run() {
                    skinsRestorer.getSkinsRestorerAPI().applySkin(new PlayerWrapper(cp),new BukkitProperty(value,signature));
               }
          }, 40L);
     }

     public static void skinChange(final CraftPlayer cp, final String value, final String signature) {
          skinsRestorer.getSkinsRestorerAPI().applySkin(new PlayerWrapper(cp),new BukkitProperty(value,signature));
          final double health = cp.getHealth();
          final Location location = cp.getLocation().add(0.0D, 1.0D, 0.0D);
          (new BukkitRunnable() {
               public void run() {
                    GameProfile profile = cp.getProfile();
                    profile.getProperties().put("textures", new Property("textures", value, signature));
                    Collection prop = profile.getProperties().get("textures");
                    cp.getProfile().getProperties().putAll("textures", prop);
                    PacketPlayOutEntityDestroy pds = new PacketPlayOutEntityDestroy(cp.getEntityId());
                    PlayerUtils.sendPacket(pds);
                    PacketPlayOutPlayerInfo tab = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, cp.getHandle());
                    PlayerUtils.sendPacket(tab);
                    cp.setHealth(0.0D);
               }
          }).runTaskLater(MegaWalls.getInstance(), 1L);
          (new BukkitRunnable() {
               public void run() {
                    cp.spigot().respawn();
                    cp.setHealth(health);
                    cp.teleport(location);
                    PacketPlayOutPlayerInfo tabadd = new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, cp.getHandle());
                    PlayerUtils.sendPacket(tabadd);
                    PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(cp.getHandle());
                    Iterator var3 = Bukkit.getOnlinePlayers().iterator();

                    while(var3.hasNext()) {
                         Player pls = (Player)var3.next();
                         if (!pls.getName().equals(cp.getName())) {
                              ((CraftPlayer)pls).getHandle().playerConnection.sendPacket(spawn);
                         }
                    }

               }
          }).runTaskLater(MegaWalls.getInstance(), 5L);
     }

     private static void sendPacket(Packet<net.minecraft.server.v1_8_R3.PacketListenerPlayOut> packet) {
          Iterator<Player> var1 = (Iterator<Player>) Bukkit.getOnlinePlayers().iterator();

          while(var1.hasNext()) {
               Player pls = var1.next();
               ((CraftPlayer)pls).getHandle().playerConnection.sendPacket(packet);
          }

     }
     public static void gatheringItem(ItemStack is, BlockBreakEvent e){
          Player p=e.getPlayer();
          Location dropLoc=e.getBlock().getLocation();
          if (MegaWalls.getInstance().getGame().isWallsFall()){
               p.getWorld().dropItem(dropLoc,is);
               return;
          }

               if (ItemUtils.isFullInventory(p.getInventory())){
                    if (ItemUtils.isFullInventory(GamePlayer.get(p.getUniqueId()).getEnderChest())){
                         p.getWorld().dropItem(dropLoc,is);
                    }else {

                         GamePlayer.get(p.getUniqueId()).getEnderChest().addItem(is);


                    }
               }else {

                    GamePlayer.get(p.getUniqueId()).getPlayer().getInventory().addItem(is);

               }

     }
     public static void gatheringItem(ItemStack[] is, BlockBreakEvent e){
          for (ItemStack itemStack:is){
               gatheringItem(itemStack,e);
          }

     }

     public static List<Player> getNearbyPlayers(Entity entity, double radius) {
          List<Player> players = new ArrayList<>();

          for (Entity e : entity.getNearbyEntities(radius, radius, radius)) {
               if (!CitizensAPI.getNPCRegistry().isNPC(e) && e instanceof Player) {
                    players.add((Player) e);
               }
          }

          return players;
     }

     public static List<Player> getNearbyPlayers(Location location, double radius) {
          List<Player> players = new ArrayList<>();

          for (Entity e : location.getWorld().getNearbyEntities(location, radius, radius, radius)) {
               if (!CitizensAPI.getNPCRegistry().isNPC(e) && e instanceof Player && e.getLocation().distance(location) <= radius) {
                    players.add((Player) e);
               }
          }

          return players;
     }

     public static void heal(Player player, double heal) {
          player.setHealth(player.getHealth() + heal > player.getMaxHealth() ? player.getMaxHealth() : player.getHealth() + heal);
     }

     public static void food(Player player, int level) {
          player.setFoodLevel(player.getFoodLevel() + level > 20 ? 20 : player.getFoodLevel() + level);
     }
}
